package org.bluedream.core.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.subject.Subject;
import org.bluedream.comm.utils.EmptyUtil;
import org.bluedream.core.config.shiro.loginOrganization.LoginOrgManager;
import org.bluedream.core.config.shiro.loginOrganization.LoginUserRealm;
import org.bluedream.core.module.login.service.LoginService;
import org.bluedream.core.module.sys.entity.Organization;
import org.bluedream.core.module.sys.entity.Role;
import org.bluedream.core.module.sys.entity.User;
import org.bluedream.core.module.sys.service.OrganizationService;
import org.bluedream.core.module.sys.service.RoleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpSession;
import java.util.Map;


public class UserUtil {
    private static Logger logger = LoggerFactory.getLogger(UserUtil.class);

    private UserUtil(){
        throw new AssertionError();
    }

    public static boolean isSystem(){
        try {
            String loginInfo = (String) getSubject().getPrincipal();
            if (loginInfo.equals(YmlRead.getValueToString("superManager"))){
                return true;
            }else {
                RoleService roleService = SpringUtil.getBean(RoleService.class);
                Role systemRole = roleService.isSystemRole(loginInfo);
                if (EmptyUtil.isNoEmpty(systemRole)){
                    return true;
                }
            }
        }catch (UnavailableSecurityManagerException var2){

        }catch (InvalidSessionException var3){
        }
        return false;
    }

    public static boolean isSystem(String loginCode){
        try {
            if ("sa".equals(loginCode)){
                return true;
            }else {
                RoleService roleService = SpringUtil.getBean(RoleService.class);
                Role systemRole = roleService.isSystemRole(loginCode);
                if (EmptyUtil.isNoEmpty(systemRole)){
                    return true;
                }
            }
        }catch (UnavailableSecurityManagerException var2){

        }catch (InvalidSessionException var3){

        }
        return false;
    }

    public static User getLoginInfo(){
        try {
            String loginInfo = (String) getSubject().getPrincipal();
            User u;
            if (loginInfo != null){
                LoginService loginService = SpringUtil.getBean(LoginService.class);
                u = loginService.getLoginUser(loginInfo);
                return u;
            }
        }catch (UnavailableSecurityManagerException var2){
        }catch (InvalidSessionException var3){
        }
        return null;
    }

/*    public static List<Organization> getOrganizations(){
        try {
            User user = getLoginInfo();
            LoginService loginService = SpringUtil.getBean(LoginService.class);
            return loginService.getOrganizations(user);
        }catch (Exception e){
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        return null;
    }*/

/*    public static List<String> getOrganizationIds(){
        try {
            User user = getLoginInfo();
            LoginService loginService = SpringUtil.getBean(LoginService.class);
            return loginService.getOrganizationIds(user);
        }catch (Exception e){
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        return null;
    }*/

    public static String getLoginOrgCode(){
        LoginOrgManager manager = SpringUtil.getBean(LoginOrgManager.class);
        String key = (String) getSession().getId();
        LoginUserRealm realm = (LoginUserRealm) manager.get(key);

        if (isLoginOrg(realm , key)){
            return realm.getOrgCode();
        }
        return null;
    }

    public static String getLoginOrgName(){
        try {
            OrganizationService organizationService = SpringUtil.getBean(OrganizationService.class);
            return organizationService.getById(getLoginOrgCode()).getTreeName();
        }catch (NullPointerException e){
            logger.error(getLoginInfo() + "获取组织信息失败，错误信息：" + e.getMessage());
            return null;
        }
    }

    /**
     * 检查当前所登录的组织是否为系统根节点
     * @return
     */
    private static boolean loginOrgCodeIsSystem(){
        try {
            OrganizationService organizationService = SpringUtil.getBean(OrganizationService.class);
            return organizationService.getSystemOrganizationId().equals(getLoginOrgCode());
        }catch (NullPointerException e){
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 当save方法不允许在 根组织节点下添加时，抛出异常
     */
    public static void allowSystemNodeSave(){
        if (loginOrgCodeIsSystem()){
            throw new RuntimeException("当前登录组织为系统根节点，不允许添加");
        }
    }

    /**
     * 验证 LoginUserRealm 是否正确
     * @param realm
     * @param sessionIdValidity
     * @return
     */
    public static boolean isLoginOrg(LoginUserRealm realm , String sessionIdValidity){
        /*
        1. 如果 LoginUserRealm 为空，则返回 false
        2. 验证 LoginOrgManager resources的key是否和session中的 LoginOrgManager.LOGIN_ORG_SUBJECT_SESSION_ID 是否一致
        3. 验证 LoginUserRealm 中的 orgCode是否和session中的 LoginOrgManager.LOGIN_ORG_MANAGER_KEY 是否一致
         */
        if (EmptyUtil.isEmpty(realm)){
            return false;
        }
        HttpSession session = realm.getLoginOrgSession();
        if (sessionIdValidity.equals(session.getAttribute(LoginOrgManager.LOGIN_ORG_SUBJECT_SESSION_ID))
                && realm.getOrgCode().equals(session.getAttribute(LoginOrgManager.LOGIN_ORG_MANAGER_KEY))){
            return true;
        }
        return false;
    }

    public static Session getSession(){
        try {
           Subject subject = getSubject();
           Session session = subject.getSession(false);
           if (session == null){
               return new SimpleSession();
           }
           return session;
        }catch (UnavailableSecurityManagerException var2){
        }catch (InvalidSessionException var3){
        }
        return new SimpleSession();
    }

    public static Subject getSubject() {
        return SecurityUtils.getSubject();
    }

    public static void testThreadContext(){
        LoginOrgManager manager = SpringUtil.getBean(LoginOrgManager.class);
        for (Map.Entry<String , Object> m1:manager.getResources().entrySet()
             ) {
            System.out.println("login org key = " + m1.getKey() + "; login org value = " + m1.getValue());
        }
    };
}
